<template>
	<div class="cl-column-custom__wrap">
		<el-button @click="open">{{ $t('自定义列') }}</el-button>

		<cl-dialog v-model="visible" :title="$t('自定义列')">
			<div class="cl-column-custom__dialog">
				<div class="left">
					<draggable v-model="list" item-key="prop">
						<template #item="{ element: item }">
							<el-checkbox v-model="item.checked" border>{{
								item.label
							}}</el-checkbox>
						</template>
					</draggable>
				</div>

				<div class="right"></div>
			</div>

			<template #footer>
				<el-button @click="close">{{ $t('取消') }}</el-button>
				<el-button type="danger" @click="reset">{{ $t('重置') }}</el-button>
				<el-button type="success" @click="save">{{ $t('保存') }}</el-button>
			</template>
		</cl-dialog>
	</div>
</template>

<script lang="ts" setup>
defineOptions({
	name: 'cl-column-custom'
});

import { ref, type PropType, nextTick, watch, computed } from 'vue';
import Draggable from 'vuedraggable/src/vuedraggable';
import { has, isBoolean, orderBy } from 'lodash-es';
import { storage } from '/@/cool';

const props = defineProps({
	name: String,
	columns: {
		type: Array as PropType<any[]>,
		required: true,
		default: () => []
	}
});

const emit = defineEmits(['update:modelValue', 'change']);

// 是否可见
const visible = ref(false);

// 名称
const name = `column-custom__${props.name || location.pathname}`;

// 列数据
const list = ref<{ label: string; prop: any; checked?: boolean; orderNum?: number }[]>([]);

// 列配置
const columns = computed(() => {
	return props.columns.filter(e => !e.type && e.prop);
});

// 改变列
function change() {
	nextTick(() => {
		columns.value.forEach(e => {
			e.hidden = !list.value.find(a => a.prop == e.prop)?.checked;
			e.orderNum = list.value.findIndex(a => a.prop == e.prop);
		});
	});
}

// 保存
function save() {
	storage.set(name, list.value);
	change();
	close();
}

// 重置
function reset() {
	columns.value.forEach(e => {
		if (e.orderNum !== undefined) {
			e.hidden = false;
			e.orderNum = 0;
		}
	});

	storage.remove(name);
	refresh();
	close();
}

// 打开
function open() {
	visible.value = true;
	refresh();
}

// 关闭
function close() {
	visible.value = false;
}

// 排序
function sort(list: any[]) {
	return orderBy(list, 'orderNum', 'asc');
}

// 刷新
function refresh() {
	if (!props.columns) {
		return false;
	}

	const selection: any[] = storage.get(name);

	list.value = sort(
		columns.value.map(e => {
			let checked = true;
			let orderNum = e.orderNum || 0;

			if (isBoolean(e.hidden)) {
				checked = !e.hidden;
			}

			if (selection) {
				checked = selection.find(a => a.prop == e.prop)?.checked;
				orderNum = selection.findIndex(a => a.prop == e.prop);
			}

			return {
				label: e.label,
				prop: e.prop,
				checked,
				orderNum
			};
		})
	);

	change();
}

// 合计
function summary(subData: { [key: string]: any }) {
	return sort(columns.value.filter(e => !e.hidden)).map(e => {
		if (has(subData, e.prop)) {
			return subData[e.prop];
		} else {
			return '';
		}
	});
}

watch(
	() => props.columns,
	() => {
		refresh();
	}
);

defineExpose({
	summary
});
</script>

<style lang="scss" scoped>
.cl-column-custom {
	&__wrap {
		margin-left: 10px;
	}

	&__dialog {
		.left {
			.el-checkbox {
				margin: 5px 10px 5px 0;
			}
		}

		.right {
			border-left: 1px solid #eee;
		}
	}
}
</style>
